import sys, platform

Import('env', 'compiler', 'lsb_build')

# svs viewer
viewer_env = env.Clone()
viewer_env['LIBS'] = []
viewer_env['CPPPATH'] = [ 'viewer', 'glfw/lib' ]
viewer_env.Append(CPPPATH = 'glfw/include')
viewer_src = Glob('viewer/*.c') + Glob('glfw/lib/*.c')

if compiler == 'msvc':
	opengl_libs = [ 'opengl32', 'glu32' ]
	viewer_env.Append(
		CPPPATH   = [ 'glfw/lib/win32' ],
		LIBS      = [ 'Ws2_32', 'Mswsock', 'AdvApi32', 'user32' ] + opengl_libs,
		LINKFLAGS = [ '/SUBSYSTEM:CONSOLE' ]
	)
	viewer_src.append('viewer/platform_specific/windows.c')
	viewer_src.extend(Glob('glfw/lib/win32/*.c'))
else:
	viewer_src.append('viewer/platform_specific/posix.c')
	if sys.platform == 'darwin':
		viewer_src.extend(Glob('glfw/lib/cocoa/*.c') + Glob('glfw/lib/cocoa/*.m'))
		opengl_libs = []  # osx uses opengl as a framework instead of libraries
		viewer_env.Append(
			CPPFLAGS  = [ '-fno-common' ],
			CPPPATH   = [ 'glfw/lib/cocoa/' ],
		)
		for f in [ 'Cocoa', 'OpenGL', 'IOKit' ]:
			viewer_env.Append(LINKFLAGS = [ '-framework', f ])
	else:
		viewer_src.extend(Glob('glfw/lib/x11/*.c'))
		opengl_libs = [ 'GL', 'GLU' ]
		viewer_env.Append(
			CPPFLAGS = [
				'-pthread',
				'-D_GLFW_HAS_PTHREAD',
				'-D_GLFW_HAS_SYSCONF',
				'-D_GLFW_HAS_SCHED_YIELD',
			],
			CPPPATH = [ 'glfw/lib/x11' ],
			LIBS    = [ 'm', 'pthread', 'X11', 'rt' ] + opengl_libs,
		)

conf = Configure(viewer_env)
missing_libs = [ l for l in opengl_libs if not conf.CheckLib(l) ]

if platform.system().startswith('Linux'):
	PROCADDRESS_FUNCS = [
		('glXGetProcAddressARB', 'GLXGETPROCADDRESSARB'),
		('glXGetProcAddress',    'GLXGETPROCADDRESS'),
		('glXGetProcAddressEXT', 'GLXGETPROCADDRESSEXT'),
	]
	macro = '_GLFW_HAS_DLOPEN'  # fallback
	for f, m in PROCADDRESS_FUNCS:
		if conf.CheckLibWithHeader('GL', 'GL/gl.h', 'C', '%s("");' % f):
			macro = m
			break;
	viewer_env.Append(CPPFLAGS='-D_GLFW_HAS_' + macro)
elif platform.system() == 'Darwin':
	viewer_env.Append(CPPFLAGS='-D_GLFW_HAS_GLXGETPROCADDRESS')

conf.Finish()

if not missing_libs:
	viewer_prog = viewer_env.Program('svs_viewer', viewer_src)
	viewer_install = viewer_env.Alias('svs_viewer', viewer_env.Install('$OUT_DIR', viewer_prog))
else:
	print 'Cannot find %s, not building svs_viewer' % ', '.join(missing_libs)

# svs library objects
svs_env = env.Clone()
svs_env['LIBS'] = []

srcdirs = ['src', 'src/filters', 'src/commands', 'src/models']
incdirs = [env.Dir(d).srcnode() for d in 'src src/models eigen ccd'.split()]
scu_src = ['SVS.cxx']

if compiler == 'g++':
	flags = [
		# By default Eigen will try to align all fixed size vectors to 128-bit
		# boundaries to enable SIMD instructions on hardware such as SSE. However,
		# this requires that you modify every class that has such vectors as members
		# so that they are correctly allocated. This seems like more trouble than
		# it's worth at the moment, so I'm disabling it.
		'-DEIGEN_DONT_ALIGN',
		'-Wno-enum-compare',
	]
	if lsb_build:
		flags.append('-DEIGEN_ALLOCA=aligned_malloc')   # alloca isn't in LSB
	
	if sys.platform == "darwin":
		srcdirs.append('src/osx')
		incdirs.append('src/osx')
		scu_src.append('src/osx/platform_specific.cpp')
	else:
		srcdirs.append('src/posix')
		incdirs.append('src/posix')
		scu_src.append('src/posix/platform_specific.cpp')

elif compiler == 'msvc':
	flags = [
		'/D', 'EIGEN_DONT_ALIGN',
		'/wd4307',
		'/wd4308',   # disables two warnings generated by Eigen code
	]
	srcdirs.append('src/windows')
	incdirs.append('src/windows')
	scu_src.append('src/windows/platform_specific.cpp')
else:
	flags = []

src = []
if env['SCU']:
	src = scu_src
else:
	for d in srcdirs:
		src += Glob(d + '/*.cpp')

svs_env.Prepend(
	CPPPATH = incdirs,
	CPPFLAGS = flags
)

ccd_env = env.Clone()
ccd_env['LIBS'] = []
ccd_env['CPPPATH'] = [env.Dir('ccd').srcnode()]
ccd_src = Glob('ccd/*.c')

if compiler == 'msvc':
	ccd_env.Append(CPPFLAGS=['/D', 'WIN32'])
	
if GetOption('static'):
	svs_objs = svs_env.Object(src) + ccd_env.Object(ccd_src)
else:
	svs_objs = svs_env.SharedObject(src) + ccd_env.SharedObject(ccd_src)

svs_inc = ['SVS/src']
Return('svs_objs', 'svs_inc')
